#pragma once
#include"Connection.hpp"
class HandlerConnection
{
    const static int buffsize = 1024;

public:
    HandlerConnection(handler_t process):_process(process){}
    HandlerConnection(){}
    void HandlerRecver(Connection* conn)
    {
        errno = 0;
        LOG(DEBUG, "%d send message\n", conn->Sockfd());
        while(1)
        {
            char buffer[buffsize];
            int n = ::recv(conn->Sockfd(), buffer, sizeof(buffer) - 1, MSG_DONTWAIT);
            if(n>0)
            {
                buffer[n] = 0;
                //放到inbuff
                conn->AppendInbuffer(buffer);
            }
            else if(n==0)
            {
                LOG(INFO, "%s:%d quit\n", conn->_addr.Ip().c_str(), conn->_addr.Port());
                conn->_handler_excepter(conn);//统一错误处理
                return;
            }
            else
            {
                if(errno==EWOULDBLOCK)
                {
                    break;
                }
                else if(errno==EINTR)
                {
                    continue;
                }
                else
                {
                    conn->_handler_excepter(conn);
                    return;
                }
            }
        }
        //这里一定是读取完毕
        cout << conn->Sockfd()<<" inbuffer:" << conn->Inbuff() << endl;
        //实际上这里可以给线程池处理，但是要加锁，还有一个问题两个都在发会导致顺序问题
        _process(conn);
    }
    void HandlerSender(Connection* conn)
    {
        errno = 0;
        while (1)
        {
            ssize_t n = ::send(conn->Sockfd(), conn->Outbuff().c_str(), conn->Outbuff().size(), MSG_DONTWAIT);
            if(n>0)
            {
                conn->DiscardOutbuffer(n);
                if(conn->Outbuff().empty())
                    break;
                
            }
            else if(n==0)
            {
                return;
            }
            else
            {
                if(errno==EWOULDBLOCK)
                {
                    break;
                }
                else if(errno==EINTR)
                {
                    continue;
                }
                else
                {
                    //异常
                    conn->_handler_excepter(conn);
                    return;
                }
            }
        }
        //到这里就是发送缓冲区满了，发送不过去 或者已经发完了而缓冲区还有空间
        if(!conn->Outbuff().empty())
        {
            //开启写入事件关系
            LOG(DEBUG, "open write\n");
            conn->_R->EnableConnectionReadWrite(conn->Sockfd(), true, true);
        }
        else
        {
            //关闭写事件
            conn->_R->EnableConnectionReadWrite(conn->Sockfd(), true, false);
        }

    }
    void HandlerExcepter(Connection* conn)
    {
        //删除连接 
        conn->_R->DelConnection(conn->Sockfd());
    }
    private:
        handler_t _process;
};
